回文日期2

题目 回文日期2

image-7532d8bf

思路分析

本来想套用上一题的做法来的 但是没考虑到很多边界情况 反而弄巧成拙

这种题 还是求稳比较好 先写出一定对的版本 再想优化 一定要保证对!

又改了一个多小时 人麻了 唉

#include<bits/stdc++.h>

using namespace std;

int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool is_leap(int year) {

    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);

}

bool check_date(int year, int month, int day) {

    if (month < 1 || month > 12) return false;

    int max_day = days[month] + (month == 2 && is_leap(year));

    return day >= 1 && day <= max_day;

}

bool check_format(int year) {//恶心 aaaa不算abab

    return (year / 100 == year % 100) && (year / 1000 != year / 100 % 10);

}

int main() {

    int curyear, curmonth, curday;

    scanf("%04d%02d%02d", &curyear, &curmonth, &curday);

    int curdate = curyear * 10000 + curmonth * 100 + curday;

    int next1 = 0, next2 = 0;

    for (int year = curyear; !next1; year++) {

        string yearStr = to_string(year);

        string rev = yearStr;

        reverse(rev.begin(), rev.end());

        int month = stoi(rev.substr(0, 2));

        int day = stoi(rev.substr(2, 2));

        if (check_date(year, month, day)) {

            int date = year * 10000 + month * 100 + day;

            if (date > curdate) {

                next1 = date;

                break;

            }

        }

    }

    for (int year = curyear; !next2; year++) {

        if (check_format(year)) {

            string yearStr = to_string(year);

            string rev = yearStr;

            reverse(rev.begin(), rev.end());

            int month = stoi(rev.substr(0, 2));

            int day = stoi(rev.substr(2, 2));

            if (check_date(year, month, day)) {

                int date = year * 10000 + month * 100 + day;

                if (date > curdate) {

                    next2 = date;

                    break;

                }

            }

        }

    }

    cout << next1 << endl << next2;

    return 0;

}
image-fc83ad4a

这种枚举年份的 有蛮多边界需要注意

要稳健好想的话 可以暴力枚举区间所有数 判断是否是日期 再判断是否是回文日期 再在回文日期的基础上判断是否为abab回文日期

然后优化一点 只枚举这个区间的有效的日期 可以参考日期差那题

找下一个合法日期:

void next_day(int &y,int &m,int &d){

d++;

if(d>get_days(y,m)){

d=1;

m++;

if(m>12){

m=1;

y++;

}

}

}

代码实现

#include<bits/stdc++.h>

using namespace std;

int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool is_leap(int y){

    return y%100 && y%4==0 || y%400==0;

}

int get_days(int y,int m){

    return days[m]+(m==2 && is_leap(y));

}

void next_day(int &y,int &m,int &d){

    d++;

    if(d>get_days(y,m)){

        d=1;

        m++;

        if(m>12){

            m=1;

            y++;

        }

    }

}

bool check_palindrome(char s[]){

    for(int i=0,j=7;i<j;i++,j--)

        if(s[i]!=s[j])

            return false;

    return true;

}

bool check_abab(char s[]){

    char a=s[0],b=s[1],c=s[2],d=s[3];

    if(a==c && b==d && a!=b)

        return true;

    return false;

}

int main()

{

    int y,m,d;

    scanf("%04d%02d%02d",&y,&m,&d);

    char s[10]={0};

    bool find1=false,find2=false;

    while(!find1 || !find2){

        next_day(y,m,d);

        sprintf(s,"%04d%02d%02d",y,m,d);

        if(check_palindrome(s)){

            if(!find1){

                puts(s);

                find1=true;

            }

            if(!find2 && check_abab(s)){

                find2=true;

                puts(s);

            }

        }

    }

    return 0;

}

同类题型

视频讲解


⬅️ 回文日期 🏠 00-刷题理模型 ➡️ 日期差值